// GameController.ts

import { _decorator, EventTarget } from 'cc';
import WebSocketManager from "./WebSocketManager";
import EventDefine from '../config/EventDefine';
import { AESUtils } from '../utils/AESUtils';

export type ResultData = {
    type: string;
    resultArray: Array<resultInfo>;
};

export class GameController {

    private static _instance: GameController;
    public memberId: string = null;
    public nickName: string = null;

    public gameRound: number = 0;
    private playerInfoList: Array<playerInfo> = [];

    public playersCount: number = 1;

    public gameAraeIndex = 0;
    public gameAreaArray: Array<areaInfo> = [];

    public eventTarget = new EventTarget();

    public currentEnergy = 0;

    public token: string = null;

    public gameResultData: ResultData = null;
    public gameResultValue: number = 0;


    private constructor() { }

    public static get Instance(): GameController {
        if (!this._instance) {
            this._instance = new GameController();
        }
        return this._instance;
    }

    public updateEnergy(energy: number) {
        this.currentEnergy += energy
    }

    public offAllEvents() {
        this.eventTarget.removeAll(this)
    }

    public reset() {
        this.currentEnergy = 0;
        this.gameRound = 0;
        this.gameResultData = null;
        this.gameResultValue = 0;
    }

    public onmessageHandle(data) {
        console.log(`[${new Date().toLocaleTimeString()}]`, data)

        switch (data.code) {
            //连接成功
            case '0':
                this.gameAreaArray = data.configArea;
                this.memberId = data.memberId;
                this.nickName = data.nickName;
                this.eventTarget.emit(EventDefine.GameUpdateNormalBetArea)
                if (data.step.code === '0') {
                    if (data.isApply === true) {
                        //已在准状态
                        const remainingTime = data.endTimestamp - data.nowTimestamp;
                        this.eventTarget.emit(EventDefine.GameReady, remainingTime)
                    }
                    else {
                        this.eventTarget.emit(EventDefine.GameConnectSuccess)
                    }
                }
                else if (data.step.code === '1') {
                    //游戏已在进行中
                    this.gameRound = parseInt(data.round)
                    this.currentEnergy = data.shield
                    this.eventTarget.emit(EventDefine.GameRunning)
                    if (data.roundMemberIsChoose === undefined) {
                        console.log('roundMemberIsChoose undefined')
                        return;
                    }

                    if (data.roundMemberIsChoose === false) {
                        const decryptedCards = data.roundCards.map(card => ({
                            ...card,
                            shield: AESUtils.decrypt(card.shield)
                        }));
                        this.eventTarget.emit(EventDefine.GameRoundCard, decryptedCards)

                        const roundRemainingTime = data.endTimestamp - data.nowTimestamp;
                        if (roundRemainingTime > 0) {
                            this.eventTarget.emit(EventDefine.GameRoundCountDown, roundRemainingTime)
                        }
                    }
                    else {
                        this.eventTarget.emit(EventDefine.GameRunningSelected)
                    }
                }
                break;
            //游戏人满传送
            case '4':
                this.eventTarget.emit(EventDefine.GameTransfer)
                break;
            //玩家数量不足 重新开局
            case '5':
                this.eventTarget.emit(EventDefine.GameRemake)
                break;
            //玩家宝石不足
            case '6':
                this.eventTarget.emit(EventDefine.GameCrystalNotEnough)
                break;
            //更新当局玩家数量
            case '7':
                this.playersCount = data.num;
                this.eventTarget.emit(EventDefine.UpdateGamePlayerNums, `${data.num}/${data.max}`)
                break;
            //更新玩家宝石
            case '9':
                this.eventTarget.emit(EventDefine.UpdateCrystal, data.memberAmount)
                break;
            //游戏准备
            case '10':
                const remainingTime = data.endTimestamp - data.nowTimestamp;
                this.eventTarget.emit(EventDefine.GameReady, remainingTime)
                break;
            //更新房间信息
            case '11':
                this.playerInfoList = data.roomInfo
                this.playersCount = this.playerInfoList.length;

                // for (let index = 0; index < this.playerInfoList.length; index++) {
                //     const element = this.playerInfoList[index];
                //       if(element.memberId == this.memberId){
                //         this.currentEnergy = element.shield;
                //         break;
                //     };
                // }

                this.eventTarget.emit(EventDefine.GameUpdatePlayersInfo, this.playerInfoList)
                break;
            //游戏回合开局
            case '12':
                this.eventTarget.emit(EventDefine.GameStart)
                break;
            //游戏回合变更
            case '13':
                this.gameRound = parseInt(data.round)
                this.eventTarget.emit(EventDefine.GameRoundRun)
                break;
            //游戏回合发牌
            case '14':
                const decryptedCards = data.cards.map(card => ({
                    ...card,
                    shield: AESUtils.decrypt(card.shield)
                }));
                this.eventTarget.emit(EventDefine.GameRoundCard, decryptedCards)
                break;
            //游戏强制选牌
            case '15':
                this.eventTarget.emit(EventDefine.GamePlayerSelectedCard, data.card)
                break;
            //游戏回合结束
            case '16':
                this.eventTarget.emit(EventDefine.GameRoundEnd)
                break;
            //游戏回合倒计时
            case '17':
                const roundRemainingTime = data.endTimestamp - data.nowTimestamp;
                this.eventTarget.emit(EventDefine.GameRoundCountDown, roundRemainingTime)
                break;
            //游戏结束
            case '18':
                this.eventTarget.emit(EventDefine.GameEnd)
                break;
            //怪兽爆炸
            case '19':
                this.eventTarget.emit(EventDefine.GameMonsterBoom)
                break;
            //游戏获胜结果
            case '20':
                const winData: ResultData = {
                    type: 'win',
                    resultArray: data.gameResult,
                }
                this.gameResultValue = parseFloat((data.bonus + data.applyAmount).toFixed(4));;
                console.log(winData)
                this.gameResultData = winData;
                // this.eventTarget.emit(EventDefine.GameResultWin, data.gameResult, data.bonus)
                this.eventTarget.emit(EventDefine.GameResultEvent)

                break;
            //游戏失败结果
            case '21':
                const loseData: ResultData = {
                    type: 'fail',
                    resultArray: data.gameResult,
                }
                this.gameResultValue = data.giftIntegral;
                console.log(loseData)
                this.gameResultData = loseData;
                this.eventTarget.emit(EventDefine.GameResultEvent)
                break;
            //游戏满足人数要求自动开始
            case '22':
                const autoStartRemain = data.endTimestamp - data.nowTimestamp;
                this.eventTarget.emit(EventDefine.GameAutoStart, autoStartRemain)
                break;

            case '24':
                this.eventTarget.emit(EventDefine.GameServicingDown)
                break;    

            //选卡后更新玩家能量值
            case '25':
                this.currentEnergy = data.roundShieldTotal;
                this.eventTarget.emit(EventDefine.GameSelectedCardUpdate)
                break;
            default:
                break;
        }
    }

    public onConnectToNewGame(joinGame: boolean) {

        if (!WebSocketManager.getInstance().socketIsOpen()) return;

        type SendData = {
            token: string;
            action: string;
            area?: string;  // 可选属性
        };

        let token = GameController.Instance.token;
        let data: SendData = {
            token: token,
            action: joinGame ? '2' : '0',
        }

        if (joinGame) {
            data.area = GameController.Instance.gameAraeIndex.toString();
        }
        else {
            data.area = '0';
        }

        WebSocketManager.getInstance().send(data);
    }

    public sendSelectedCardInfo(info: cardInfo) {
        if (!WebSocketManager.getInstance().socketIsOpen()) return;

        let token = GameController.Instance.token;
        let data = {
            token: token,
            action: "15",
            card: {
                id: info.id,
                type: info.type,
                round: this.gameRound,
                shield: AESUtils.encrypt(info.shield)
            }
        }
        WebSocketManager.getInstance().send(data);
    }

    public closeWebSocket() {
        WebSocketManager.getInstance().close()
    }
}
